home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------
- | Wir erstellen 3-D-Bilder
- | Eingabe-File:
- | a... Figur ist hinter Bildebene
- | 1... Figur ist vor Bildebene
- | SPACE Bildebene
- | zB:
- | 11
- | 12222221
- | 12233333333221
- | 1223333443333221
- | 12233344443333221
- | 1223333443333221
- | 12233333333221
- | 12222221
- | 11
- | Gibt so was wie 'ne Kugel, klar?
- --------------------------------------*/
-
- /*---------------------------------------------------------------------*/
- /*----------------------------
- | Wenn TEST
- | definiert ist, werden
- | einige Infos ausgegeben,
- | die ich zum Testen brauche
- ------------------------------*/
-
- /*------------------------
- | Informationen ausgeben?
- -------------------------*/
- #if 01
- #define TEST
- #endif
-
- /*-------
- | Welche?
- --------*/
- #if defined (TEST)
-
- #if 0
- #define PROFIL
- #define SAME_NUMBERS
- #define VERBOSE
- #define PATTERNS
- #define OFFSETS
- #define NO_GRAFIK
- #endif
-
- #if 1
- #define VERSION
- #define GRAFIK_INFO
- #define ERRORS
- #endif
-
- #endif
-
- #if !defined (NO_GRAFIK)
- #define GRAFIK
- #endif
-
-
- /*---------------------------------------------------------------------*/
- #include <ctype.h>
- #include <ext.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
-
- #include "tools.h" /*------------------------------------------
- | Optionen aus Kommando-Zeile holen
- | File-Routinen:
- | load_file(): File laden, Länge ermitteln
- | unload_file(): dasselbe entfernen
- | get_pn(): Pfad und Namen aus String holen
- --------------------------------------------*/
-
-
- /*--------------------------
- | Zulässige Optionen für DDD
- ----------------------------*/
- #define PLINE_FLG "/p"
- #define PFILE_FLG "/q"
- #define FREQUENZ_FLG "/f"
-
-
-
-
- /*--------------------------------------------------------------------------*/
- #define STD_FRQ 16 /* Das Muster wiederholt sich! */
- #define EBENEN 8 /* Muß immer kleiner als std_frq sein */
- #define MIN_LINE 80 /* Mindestgröße für das Bild */
- #define MIN_ROW 25 /* Mindestgröße für das Bild */
-
- /*-----------------------------------------
- | Ebenen vor und hinter der Bildebene
- | NB: ASCII-Zeichen eintragen ('1' statt 1)
- -------------------------------------------*/
- #define MAX_VORNE ('1'+EBENEN)
- #define MAX_HINTEN ('a'+EBENEN)
- #define ERROR 0
-
- #define max(a, b) ((a) > (b) ? (a) : (b))
- #define min(a, b) ((a) < (b) ? (a) : (b))
-
-
-
- /*--------------------------------------------------------------------------*/
- /*-------------------------------------
- | Hier werden die Optionen gespeichert:
- | 2. Parameter == NULL <-> Listenende
- ---------------------------------------*/
- opt_list liste[] = { { PLINE_FLG, get_string, NULL, FALSE},
- { PFILE_FLG, get_string, NULL, FALSE},
- { FREQUENZ_FLG, get_number, NULL, FALSE},
- { NULL, NULL, NULL, FALSE}
- };
-
-
- /*---------
- | Bildgröße
- -----------*/
- int cc; /* Anzahl Zeichen im Bild */
- int _cc; /* dito, in Text */
- int rc; /* Anzahl Zeilen */
- int _lo; /* Offset zum Zentrieren */
- int ro; /* innerhalb der Graphik */
-
-
- /*---------------
- | Muster-Speicher
- -----------------*/
- char *My_Pattern;
- long pattern_size;
- int std_frq;
- int max_frq;
-
- /*------------------------------
- | Hier wird der Text gespeichert
- --------------------------------*/
- char *text;
- int file_flg; /* File? */
-
- /*------------------------------
- | Die Muster für den Hintergrund
- --------------------------------*/
- char *pattern;
- /*---------------------------------------
- | Der Text in Höheninformation übersetzt.
- ----------------------------------------*/
- char *picture;
- /*-----------------------
- | Speicher für 3D-Grafik
- -------------------------*/
- char *grafik;
-
-
-
- /*--------------------------------------------------------------------------*/
- /*----------
- | Prototypen
- ------------*/
- void free_text( void ); /* atexit-Funktionen */
- void new_line( void );
-
- int set_options( opt_list *l); /* Optionen auswerten */
-
- int get_picture_size( char *f); /* Größe und Inhalt abfragen */
-
- void print_picture( void ); /* Höheninformationen ausgeben */
- void print_grafik( void ); /* 3d-Grafik ausgeben */
- void print_pattern( char *pattern); /* Zum Testen: Pattern ausgeben */
-
- void fill_picture( char *picture, char *text); /* Umwandlungsroutinen */
- int get_offset( char c);
- void transform_picture( char *grafik, char *picture);
-
- void make_patterns( char *pattern, int rc ); /* Muster erstellen und anpassen */
- void remake_pattern( char *pattern, int frequenz, int i, int c);
- int make_pixel( char *pattern );
-
-
- /*--------------------------------------------------------------------------*/
- /*-------------
- | Start of Code
- ---------------*/
- main( int argc, char *argv[])
- {
- char p[140], n[14];
- time_t tm;
- int opt_c;
-
-
- new_line();
- atexit( new_line);
-
- #if defined (SAME_NUMBERS)
- srand( 1 );
- #endif
-
- #if defined (VERSION)
- printf("\nDD.TTP (vers. %s)", __DATE__ );
- #endif
-
- /*-----------------
- | Optionen einlesen
- | und auswerten
- -------------------*/
- opt_c = get_options( argc, argv);
- if( set_options( liste ) == FALSE )
- { exit( 0 );
- }
-
-
- /*---------------
- | Falsche Angaben
- -----------------*/
- if( opt_c == argc )
- { printf("\n3-D grafix creator."
- "\nusage: ddd [/pPATTERNLINE] [/qPATTERNFILE] [/fFREQUENZ] input_file"
- "\nsee ddd.txt for more information.");
- exit( 0 );
- }
-
- /*-------------------
- | Eingabe_file laden:
- ---------------------*/
- get_pn( p, n, argv[opt_c] );
-
- text = (char *)load_file( p, n, "r" );
- if( text == NULL )
- { printf( "\nnot found: %s%s", p, n);
- return -1;
- }
-
- /*------------------
- | Text_Informationen
- --------------------*/
- time( &tm );
- printf("\n%s, compiled on %s", n, ctime( &tm) );
-
- /*--------------------
- | Jetzt geht's looooos
- ----------------------*/
- if( get_picture_size( text ) == 0)
- {
- grafik = ( char *)malloc( cc * rc );
- picture = ( char *)malloc( cc * rc );
- pattern = ( char *)malloc( max_frq * rc );
-
- /*------------------------------------
- | Text in Höheninformationen umwandeln
- | *picture mit Daten von *text füllen
- --------------------------------------*/
- fill_picture( picture, text);
-
- #if defined (PROFIL)
- /*-------------------
- | *picture darstellen
- ---------------------*/
- printf("\n\nHöhenprofil\n");
- print_picture( );
- #endif
-
- /*--------------------------
- | Die Zufallsmuster erzeugen
- ----------------------------*/
- make_patterns( pattern, rc );
-
- /*------------------------------
- | picture in 3-D Bild übertragen
- | Ändert patterns.
- --------------------------------*/
- transform_picture( grafik, picture );
-
-
- /*-----------------
- | 3-D Bild ausgeben
- -------------------*/
- #if defined (GRAFIK)
- print_grafik( );
- #endif
-
- free( pattern );
- free( picture );
- free( grafik );
- }
- unload_file( text );
-
- return 0;
- }
-
-
- /*--------------------------
- | atexit()
- ----------------------------*/
- void free_text( void )
- {
- unload_file( My_Pattern );
- }
-
-
- void new_line( void )
- { printf("\n");
- }
-
-
- /*----------------------------------------------------
- | Optionen auswerten:
- ------------------------------------------------------*/
- int set_options( opt_list *l)
- {
- char p[200], n[14];
- long c;
-
- /*-----------------
- | Globale Variablen
- -------------------*/
- pattern_size = std_frq = STD_FRQ;
- My_Pattern = NULL;
- file_flg = FALSE;
-
- if( l[0].valid && l[1].valid )
- { printf("\nOptionen %s und %s schließen sich aus!", PLINE_FLG, PFILE_FLG);
- return FALSE;
- }
-
- /*-------------
- | Eingabe_Zeile
- ---------------*/
- if( l[0].valid )
- {
- pattern_size = std_frq = (int)strlen( l[0].value );
- My_Pattern = (char *)malloc( std_frq + EBENEN);
- strcpy( My_Pattern, l[0].value );
- }
-
-
- /*------------
- | Eingabe-File
- --------------*/
- if( l[1].valid )
- {
- get_pn( p, n, l[1].value );
- My_Pattern = (char *)load_file( p, n, "r" );
- if( My_Pattern == NULL )
- { printf("\ncan't load %s%s", p, n);
- }else
- { /*---------------------------------
- | Nur Zeichen >= SPACE sind erlaubt
- | SPACE -> '_'
- | Der Rest wird übersprungen
- -----------------------------------*/
- for( c = 0; c < act_fil_sz; c++)
- { if( My_Pattern[c] < ' ' )
- { memcpy( &My_Pattern[c], &My_Pattern[c+1], act_fil_sz-c);
- c--;
- act_fil_sz--;
- }
- if( My_Pattern[c] == ' ' )
- { My_Pattern[c] = '_';
- }
- }
- pattern_size = act_fil_sz;
-
- /*------------
- | Was bin ich?
- --------------*/
- file_flg = TRUE;
-
- atexit( free_text );
- }
- }
-
-
- /*---------
- | Frequenz:
- -----------*/
- if( l[2].valid )
- { std_frq = (int)l[2].value;
- if( l[0].valid)
- { std_frq = min( std_frq, (int )strlen( l[0].value ) );
- }
- }
-
- max_frq = std_frq + EBENEN;
-
- return TRUE;
- }
-
- /*-------------------------------------------------------------------
- | Bild analysieren
- ---------------------------------------------------------------------*/
-
- /*-------------------------------
- | Wie lang ist die längste Zeile?
- | Wie viele Zeilen hat das Bild?
- | Zeichen checken.
- ---------------------------------*/
- int get_picture_size( char *f)
- {
- long c;
- int al;
- int ret;
- char t;
-
- ret = 0;
-
- al = cc = 0;
-
- for( c = 0; c < act_fil_sz; c++ )
- {
- t = *(f+c);
- if( (t >= '1' && t <= MAX_VORNE) ||
- (t >= 'a' && t <= MAX_HINTEN) ||
- t == '\n' || t == ' ')
- { ;
- }else
- { printf("\nFile enthält falsches Zeichen >>%c<<in Zeile %d, Spalte %d", t, rc, al);
- ret |= ~0;
- }
- if( *(f + c) == '\n' )
- { cc = max( al, cc );
- al = 0;
- rc++;
- }
- al++;
- }
-
-
- ro = _lo = 0;
-
- /*----------------------------------
- | So groß ist das Bild wirklich:
- | (wird von fill_picture() benötigt)
- ------------------------------------*/
- _cc = cc;
-
- /*-----------------------------------
- | Noch einen Rahmen um's Bild machen.
- | Weil's leichter zu sehen ist.
- -------------------------------------*/
- cc += std_frq * 2;
-
- /*----------------
- | Bild zentrieren:
- ------------------*/
- if( cc < MIN_LINE )
- { cc = MIN_LINE;
- }
- _lo = ( cc - _cc ) / 2;
-
-
- if( rc < MIN_ROW )
- { ro = (MIN_ROW - rc) / 2;
- rc = MIN_ROW;
- }
-
- #if defined (VERBOSE)
- printf("\n%d * %d / offset: %d, %d", cc, rc, _lo, ro );
- printf("\n%ld Bytes in file", act_fil_sz);
- #endif
-
- return ret;
- }
-
-
-
- /*-------------------------------------------------------------------
- | Bildschirmausgabe
- ---------------------------------------------------------------------*/
-
- /*-----------------------------------------
- | Auf den Schirm!
- | 3d-codiertes Bild
- -------------------------------------------*/
- void print_grafik( void )
- {
- int x, y;
- long o;
-
- #if defined (VERBOSE)
- printf("\n\n3d-Grafik: Frequenz = %d \n", std_frq);
- #endif
-
- /*----------------------
- | Markierungen schreiben
- ------------------------*/
- printf("\n");
- for( x = 0; x < (MIN_LINE - std_frq) / 2; x++)
- printf(" ");
- printf("x");
- for( x = 1; x < std_frq; x++)
- printf(" ");
- printf("x");
-
- for( y = 0; y < rc; y++ )
- {
- printf("\n");
-
- for( x = 0; x < cc; x++ )
- { o = x + y * cc;
- /*----------------
- | Nächste Stelle
- ------------------*/
- printf("%c", grafik[o] );
- }
-
- }
- printf("\n\n");
- #if defined (TEST)
- getch();
- #endif
- }
-
-
- /*-----------------------------------------
- | Auf den Schirm!
- | Zahlwerte + EBENEN werden ausgegeben.
- | -> Werte liegen zwischen 0 und 2 * EBENEN
- | EBENEN = Leere Fläche
- | 0 = Nächste Ebene
- | 2 * EBENEN = entfernteste Ebene
- -------------------------------------------*/
- void print_picture( void )
- {
- int x, y;
- long o;
-
- for( y = 0; y < rc; y++ )
- {
- printf("\n ");
-
- for( x = 0; x < cc; x++ )
- { o = x + y * cc;
- /*----------------
- | Nächste Stelle
- ------------------*/
- printf("%d", picture[o] + EBENEN);
- }
-
- }
- getch();
- }
-
-
-
-
- /*----------------
- | Testfunktion:
- | Pattern ausgeben
- ------------------*/
- void print_pattern( char *p)
- {
- int i;
-
- for( i = 0; i < max_frq; i++)
- { printf("%c", *( p + i ) );
- }
- }
-
-
-
- /*---------------------------------------------------------------------
- | Hilfsfunktionen
- -----------------------------------------------------------------------*/
-
-
-
- /*-----------------------
- | Zufallsmuster erstellen
- -------------------------*/
- void make_patterns( char *pattern, int rc )
- {
- int c, d;
- int y;
- int po;
- char h;
-
- c = 0;
-
- for( y = 0; y < rc; y++ )
- {
- po = y * max_frq;
-
- /*--------------------------------
- | String mit Zufallszeichen füllen
- ----------------------------------*/
- for( d = 0; d < std_frq ; d++ )
- {
- /*--------------
- | Muster füllen:
- ----------------*/
- if( My_Pattern )
- { /*------------------------
- | Brief:
- | Letztes Zeichen ist '|'
- | wg Lesbarkeit
- -------------------------*/
- if( file_flg && (d == std_frq - 1 ) )
- { h = '|';
- }else
- { h = My_Pattern[ c++ % pattern_size];
- }
- }else
- { /*-----------
- | Zufallszahl
- -------------*/
- h = make_pixel( pattern + po);
- }
- pattern[ po + d ] = h;
- }
- }
- }
-
-
- /*----------------------------
- | einen Zufalls-Wert erzeugen,
- | wie ihn die grafik braucht.
- | Keine Wiederholung zulassen
- ------------------------------*/
- int make_pixel( char *pattern )
- {
- int i;
- int c;
- int go;
-
- do
- {
- c = rand( ) / 600 + ' ' + 1 ;
-
- go = 0;
- for( i = 0; i < max_frq; i++ )
- {
- if( c == pattern[i] )
- { go = ~0;
- break;
- }
- }
- }while( go );
-
- return c;
- }
-
-
- /*--------------------------------------
- | Zufallsmuster ändern:
- |---------------------------------------
- | Im Pattern pattern
- | der Länge f (alte Länge)
- | ab index i
- | c Zeichen einfügen (c > 0 )
- | (neue Werte erzeugen)
- | c Zeichen löschen (c < 0 )
- ----------------------------------------*/
- void remake_pattern( char *pattern, int f, int i, int c)
- {
- int d;
-
- #if defined (PATTERNS)
- print_pattern( pattern );
- printf(" adr: %8lx / f: %2d / i: %2d / c: %2d\n", pattern, f, i, c);
- #endif
-
- /*-------
- | Löschen
- ---------*/
- if( c < 0 )
- {
- /*------------------
- | Muster verschieben
- --------------------*/
- memcpy( pattern + i , pattern + i + abs(c) , f - i - abs(c) );
-
- }else
- /*--------
- | Einfügen
- ----------*/
- {
- /*------------------
- | Muster verschieben
- --------------------*/
- memcpy( pattern + i + c, pattern + i, f - i );
-
- /*---------------------
- | Zeichen überschreiben
- -----------------------*/
- for( d = i; d < i + c; d++ )
- { *(pattern + d ) = make_pixel( pattern );
- }
- }
-
- #if defined (PATTERNS)
- print_pattern( pattern );
- #endif
-
- }
-
- /*-------------------------------------------
- | Wie weit muß das Zeichen verschoben werden?
- | Eingabe: Zeichen für Höhe (ASCII-File)
- | Ausgabe: Offset für 3D-File
- ---------------------------------------------*/
- int get_offset( char c)
- {
- int offset;
-
- if( c == ' ' )
- { offset = 0;
- }else if( c >= '1' && c <= MAX_VORNE)
- { offset = '1' - c - 1;
- }else if( c >= 'a' && c <= MAX_HINTEN)
- { offset = c - 'a' + 1;
- }else
- {
- #if defined (ERRORS)
- printf("\nFalscher Wert: %d", c);
- #endif
- offset = ERROR;
- }
-
- return offset;
- }
-
-
- /*-------------------------------------------------------------------
- | Umwandlungsroutinen
- ---------------------------------------------------------------------*/
-
- /*-----------------------------------
- | Das Bild wird mit den Informationen
- | über die Höhe gefüllt.
- | Bild ist zentriert!
- |------------------------------------
- | Es gilt:
- | Wert < 0: Bild liegt vor Ebene
- | Wert = 0: Bild liegt in Ebene
- | Wert > 0: Bild liegt hinter Ebene
- -------------------------------------*/
- void fill_picture( char *picture, char *text)
- {
- int x, y;
- int to;
-
-
- to = 0;
-
- for( y = 0; y < rc; y++)
- {
- for( x = 0; x < cc; x++)
- {
- /*---------------
- | Rahmen erzeugen
- -----------------*/
- if( y < ro || y > rc - ro || x < _lo || x > cc - _lo )
- { *picture++ = 0;
- }else
- {
- /*---------------------------
- | Bildinformationen speichern
- -----------------------------*/
- if( to < act_fil_sz && text[to] != '\n' )
- { *picture++ = get_offset( text[to] );
- to++;
- }else
- { *picture++ = 0;
- }
- }
- }
- if( y >= ro && to < act_fil_sz )
- { to++;
- }
- }
- }
-
-
- /*-------------------------------------------------------------
- | In das Feld wird eingetragen, welcher Offset im Muster in die
- | 3d-Grafik gehört.
- ---------------------------------------------------------------
- | selbe Höhe -> gleicher Offset
- | x näher -> Offset - x
- | x weiter -> Offset + x
- ---------------------------------------------------------------*/
- void transform_picture( char *grafik, char *picture)
- {
- int x, y; /* Wo sind wir? */
- int offset; /* Abstand Hintergrund / Bildpunkt */
- int alter_offset; /* vorheriger Wert */
- int d_o; /* Änderung im Offset */
- int frequenz; /* Wiederholung des Musters */
- int t; /* Helferlein */
- int i; /* Index für Zufallsmuster */
- int pp; /* Pointer auf aktuelles Pattern */
-
-
- #if defined (OFFSETS)
- printf("\033E\n\nOffset-Erstellung");
- #endif
-
- for( y = 0; y < rc; y++)
- {
- /*-------------------
- | Da steht das Muster
- ---------------------*/
- pp = y * ( max_frq );
-
- #if defined (OFFSETS)
- printf("\n");
- #endif
-
- /*------------------
- | Anfang des Musters
- --------------------*/
- i = 0;
- frequenz = std_frq;
- alter_offset = 0;
-
- /*---------------------
- | Von rechts nach links
- -----------------------*/
- for( x = 0; x < cc; x++)
- {
- /*------------
- | Da sind wir:
- --------------*/
- t = y * cc + x;
-
-
- /*-----------------------------------------
- | offset gibt an, um wieviel das Muster an der
- | entsprechenden Stelle verschoben sein muß.
- | offset ist ok!
- -------------------------------------------*/
- offset = picture[ t ];
-
- /*------------------------
- | rel. Änderung im Muster:
- -------------------------*/
- d_o = offset - alter_offset;
-
-
- #if defined (OFFSETS)
- /*-------------------------
- | Normale Schrift
- ---------------------------*/
- printf("\033q");
- #endif
- /*----------------------------
- | Es gibt eine Änderung
- | -> Altes (!) Muster anpassen
- | also auch: alte Parameter
- -----------------------------*/
- if( d_o )
- {
- #if defined (OFFSETS)
- /*---------------
- | Inverse Schrift
- -----------------*/
- printf("\033p");
-
- #endif
- remake_pattern( pattern + pp, frequenz, i, d_o);
- alter_offset = offset;
- }
-
- /*----------------------------------------------------------
- | Werte neu berechnen
- -----------------------------------------------------------*/
-
- /*--------------
- | Neue Frequenz:
- ----------------*/
- frequenz = std_frq + offset;
-
- /*-------------------------------
- | index an neue Frequenz anpassen
- --------------------------------*/
- if( d_o )
- { i %= frequenz;
- }
-
- /*-------------------------------
- | Wert im Grafikspeicher ablegen
- ---------------------------------*/
- grafik[ t ] = pattern[ pp + i ];
-
- /*--------------
- | Nächster Index
- ----------------*/
- i = (i + 1) % frequenz;
-
- /*---------------------------------
- | Information auf Bildschirm zeigen
- -----------------------------------*/
- #if defined (OFFSETS)
- #if 0
- /*-----------------------------
- | Offsets:
- | Nur die mittleren 40 Zeichen!
- -------------------------------*/
- if( abs( MIN_LINE / 2 - x ) < 20 )
- {
- printf("%2d", i);
- }
- #else
- /*-------------
- | Grafik: Alles
- ---------------*/
- printf("%c", grafik[t] );
-
- #endif
- #endif
- }
- }
-
- #if defined (OFFSETS)
- getch();
- #endif
-
- }
-
-